package ru.yandex.api.money.oauth;

import javax.servlet.http.HttpServletRequest;

import org.json.JSONException;
import org.json.JSONObject;

import ru.yandex.api.money.util.RequestBuilder;

/**
 * @author: Melnikov Ivan melnikov.ivan@gmail.com
 */
public class AuthService {

	public static final String CODE_PARAMETER = "code";
	
	private final String client_id;

	private String authServer = "https://sp-money.yandex.ru";
	
	public AuthService(String client_id) {
		this.client_id = client_id;
	}

	/**
	 * @return redirect url for user to approve 
	 */
	public String authorize(String callbackUrl, Scope...scope) {
		String scopes = Scope.scopes(scope);
		RequestBuilder request = new RequestBuilder(authServer+"/oauth/authorize")
				.addParam("client_id", client_id)
				.addParam("redirect_uri", callbackUrl)
				.addParam("response_type", "code")
				.addParam("scope", scopes);
		return request.redirect();
	}

	/**
	 * @return access_token for requested scopes 
	 */
	public String getAccessToken(HttpServletRequest request, String callbackUrl) {
		String code = request.getParameter(CODE_PARAMETER);
		if (code == null || code.isEmpty()) {
			String error = request.getParameter("error");
			processError(error);
			return null;
		}
		
		return getAccessToken(code, callbackUrl);
	}

	/**
	 * @return access_token for requested scopes 
	 */
	public String getAccessToken(String code, String callbackUrl) {
		String content = new RequestBuilder(authServer+"/oauth/token")
					.addParam("client_id", client_id)
					.addParam("redirect_uri", callbackUrl)
					.addParam("code", code)
					.addParam("grant_type", "authorization_code")
					.build();
			
		try {
			JSONObject result = new JSONObject(content);
			if (!result.has("access_token")) {
				throw new RuntimeException("No access token:\n"+content);
			}
			return result.getString("access_token");
		} catch (JSONException e) {
			e.printStackTrace();
			System.out.println(content);
			return null;
		}
	}

	protected static void processError(String error) {
		if ("access_denied".equals(error)) {
			
		}
		// other errors
	}

	// set another auth server , e.g. for testing
	public void setAuthServer(String authServer) {
		this.authServer = authServer;
	}
	
}
